package com.smart.translator.util;

public class AdpcmDecoder {
    // IMA ADPCM step variation table
    private static final int[] stepSize = {
        7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
        19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
        50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
        130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
        337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
        876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
        2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
        5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
        15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
    };

    private static final int[] stepAdjustment = {
        -1, -1, -1, -1, 2, 4, 6, 8
    };

    private int last;
    private int stepIndex;

    public AdpcmDecoder() {
        reset();
    }

    public void reset() {
        last = 0;
        stepIndex = 0;
    }

    private short saturate(int amp) {
        if (amp > Short.MAX_VALUE)
            return Short.MAX_VALUE;
        if (amp < Short.MIN_VALUE)
            return Short.MIN_VALUE;
        return (short) amp;
    }

    private short decode(byte adpcm) {
        int e;
        int ss;
        short linear;

        ss = stepSize[stepIndex];
        e = ss >> 3;
        if ((adpcm & 0x01) != 0)
            e += (ss >> 2);
        if ((adpcm & 0x02) != 0)
            e += (ss >> 1);
        if ((adpcm & 0x04) != 0)
            e += ss;
        if ((adpcm & 0x08) != 0)
            e = -e;

        linear = saturate(last + e);
        last = linear;
        
        // 修正：直接使用adpcm & 0x07，与C语言实现一致
        stepIndex += stepAdjustment[adpcm & 0x07];
        if (stepIndex < 0)
            stepIndex = 0;
        else if (stepIndex > 88)
            stepIndex = 88;

        return linear;
    }

    public short[] decode(byte[] adpcmData) {
        if (adpcmData == null || adpcmData.length == 0)
            return new short[0];

        // 跳过前4个字节的帧头
        int dataLength = adpcmData.length - 4;
        if (dataLength <= 0)
            return new short[0];

        short[] pcmData = new short[dataLength * 2]; // 每个ADPCM字节解码为2个PCM样本
        int pcmIndex = 0;

        // 从第5个字节开始解码
        for (int i = 4; i < adpcmData.length; i++) {
            byte adpcm = adpcmData[i];
            // 每个字节包含两个4位的ADPCM样本
            pcmData[pcmIndex++] = decode((byte) (adpcm & 0x0F)); // 低4位
            pcmData[pcmIndex++] = decode((byte) ((adpcm >> 4) & 0x0F)); // 高4位
        }

        return pcmData;
    }

    // 新增：解码无帧头的ADPCM数据
    public short[] decodeWithoutHeader(byte[] adpcmData) {
        if (adpcmData == null || adpcmData.length == 0)
            return new short[0];

        // 直接解码所有数据，不跳过帧头
        short[] pcmData = new short[adpcmData.length * 2]; // 每个ADPCM字节解码为2个PCM样本
        int pcmIndex = 0;

        // 解码所有字节
        for (int i = 0; i < adpcmData.length; i++) {
            byte adpcm = adpcmData[i];
            // 每个字节包含两个4位的ADPCM样本
            pcmData[pcmIndex++] = decode((byte) (adpcm & 0x0F)); // 低4位
            pcmData[pcmIndex++] = decode((byte) ((adpcm >> 4) & 0x0F)); // 高4位
        }

        return pcmData;
    }
} 